#ifndef CHAINSAW_COMMON_STRINGTOOL_STRINGTOOL_H
#define CHAINSAW_COMMON_STRINGTOOL_STRINGTOOL_H

#include <string>
#include <vector>

namespace chainsaw
{
    enum class split_part
    {
        LEFT,
        RIGHT
    };
    class stringtool
    {
    public:
        stringtool(std::string s) : m_data(s) {}

        // Find the first occurrence of character c in the data.
        // Returns the position if found, otherwise -1.
        // Example:
        //   int res = find('a');
        //   if (!~res) -> not found
        int find(char c) const;

        // Find the first occurrence of substring s in the data.
        // Returns the starting position if found, otherwise -1.
        // Example:
        //   int res = find("test");
        //   if (!~res) -> not found
        int find(std::string const &s) const;

        // find all character c
        std::vector<int> find_all(char c) const;

        // [beginpos, endpos)
        std::string substr(int beginpos, int endpos) const;

        // [0,pos)&&(pos, size]
        // num:
        // 0->[0,pos)
        // 1->(pos, size]
        std::string split(int pos, split_part part) const;

        //
        std::vector<std::string> split(std::vector<int> pos) const;

        // xxx[p]xxx -> xxx[v]xxx
        // pos:p-position
        // value:v
        std::string replaced(int pos, char value) const;

        std::string replace(int pos, char value);

        // [hello world!] ->
        // [hello][world]
        std::vector<std::string> splitWord() const;

        // [space]xxx[space] -> xxx
        std::string trimmed() const;

        std::string trim();

        // [abcdxxx],n=5 -> [abcdx]
        std::string left(int n = 0) const;

        // [abcdxxx],n=4 -> [dxxx]
        std::string right(int n = 0) const;

        //
        char head() const;

        //
        char tail() const;

        //
        bool startsWith(std::string s) const;

        //
        bool endsWith(std::string s) const;

        //
        int size() const;

        // abcd,n=2 -> cd
        std::string remove_head(int n = 1);

        std::string remove_tail(int n = 1);

        // print ctor-input data
        void print() const;

        // return original data
        std::string operator()() const;

        char operator[](int index) const;

        bool empty() const;
    private:
        std::string m_data;

    private:

        bool is_index_valid(int index) const;
    };

    bool is_word(std::string const &s);

    // aBC -> ABC
    std::string to_upper(std::string str);

    // Abc -> abc
    std::string to_lower(std::string str);

    void trim(std::vector<std::string> &data);

} // namespace chainsaw

#endif // !CHAINSAW_COMMON_STRINGTOOL_STRINGTOOL_H
